/* USER CODE BEGIN Header */

#include "bs_ring_buf.h"
#include <math.h>
#include <string.h>
#define MIN(a, b)     (((a)>(b)) ? (b): (a))

#define DISABLE_IRQ
#define RESTORE_IRQ

void circ_buf_init(circ_buf_t *circ_buf, uint8_t *buffer, uint32_t size)
{
    DISABLE_IRQ
    circ_buf->buf = buffer;
    circ_buf->size = size;
    circ_buf->head = 0;			
    circ_buf->tail = 0;
    RESTORE_IRQ
}

void circ_buf_reset(circ_buf_t *circ_buf)
{
	DISABLE_IRQ
    circ_buf->head = 0;			
    circ_buf->tail = 0;
    memset(circ_buf->buf, 0, circ_buf->size);
	RESTORE_IRQ
}

void circ_buf_push(circ_buf_t *circ_buf, uint8_t data)
{
	DISABLE_IRQ
    circ_buf->buf[circ_buf->tail] = data;
    circ_buf->tail += 1;

    if (circ_buf->tail >= circ_buf->size) {
        circ_buf->tail = 0;
    }
	RESTORE_IRQ
}


uint8_t circ_buf_pop(circ_buf_t *circ_buf)
{
    // DISABLE_IRQ
    uint8_t data;
    data = circ_buf->buf[circ_buf->head];
    circ_buf->head += 1;

    if (circ_buf->head >= circ_buf->size) {
        circ_buf->head = 0;
    }
	  // RESTORE_IRQ
    return data;
}

uint32_t circ_buf_count_used(circ_buf_t *circ_buf)
{
    DISABLE_IRQ
    uint32_t cnt;
    if (circ_buf->tail >= circ_buf->head) {
        cnt = circ_buf->tail - circ_buf->head;
    } else {
        cnt = circ_buf->tail + circ_buf->size - circ_buf->head;
    }
	  RESTORE_IRQ
    return cnt;
}

uint32_t circ_buf_count_free(circ_buf_t *circ_buf)
{
    DISABLE_IRQ
    uint32_t cnt;
    cnt = circ_buf->size - circ_buf_count_used(circ_buf) - 1;
    RESTORE_IRQ
    return cnt;
}

uint32_t circ_buf_read(circ_buf_t *circ_buf, uint8_t *data, uint32_t size)
{
    uint32_t cnt;
    uint32_t i;
    cnt = circ_buf_count_used(circ_buf);
	DISABLE_IRQ
    cnt = MIN(size, cnt);
	
    for (i = 0; i < cnt; i++) {
        data[i] = circ_buf_pop(circ_buf);
    }
	RESTORE_IRQ
    return cnt;
}


uint32_t circ_buf_write(circ_buf_t *circ_buf, const uint8_t *data, uint32_t size)
{
    uint32_t cnt;
    uint32_t i;
    cnt = circ_buf_count_free(circ_buf);
    cnt = MIN(size, cnt);
    for (i = 0; i < cnt; i++) {
        circ_buf_push(circ_buf, data[i]);
    }
    return cnt;
}
